package com.sy.dao.impl;

import com.sy.dao.CarDao;
import com.sy.entity.Car;
import com.sy.vo.CarSearchParams;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import static com.sy.constant.BusinessConstant.ALL_BRAND_ID;
import static com.sy.constant.BusinessConstant.ALL_PRICE_RANGE_ID;
import static com.sy.constant.BusinessConstant.ALL_TYPE_ID;
import static com.sy.constant.BusinessConstant.DEFAULT_PAGE_SIZE;

public class CarDaoImpl extends AbstractDaoImpl implements CarDao {

    @Override
    public List<Car> getCarsByConditions(CarSearchParams searchParams, Integer start) {
        StringBuilder sql = new StringBuilder("select * from t_car where 1=1 ");
        //这里由于前端查询界面中是一个组合查询的界面，条件的组合变化情况很多
        //如果对于每个情况都去定义一个查询方法，会非常麻烦，所有这里封装了一个方法
        //根据传递过来的参数决定SQL语句查询条件的结构，动态进行SQL语句中条件的拼接，
        //这样就可以用一个方法去解决所有情况下的组合查询了。
        WhereClause whereClause = buildWhereClause(searchParams);
        sql.append(whereClause.getSql());
        List<Object> params = whereClause.getParams();
        if (Objects.nonNull(start)) {
            sql.append(" limit ?,? ");
            params.add(start);
            params.add(DEFAULT_PAGE_SIZE);
        }
        System.out.println("SQL:" + sql);
        return queryForList(sql.toString(), Car.class, params.toArray());
    }

    @Override
    public Long getCarsCountByConditions(CarSearchParams params) {
        StringBuilder sql = new StringBuilder("select count(*) from t_car where 1=1 ");
        WhereClause whereClause = buildWhereClause(params);
        sql.append(whereClause.getSql());
        System.out.println("SQL:" + sql);
        return queryForValue(sql.toString(), whereClause.getParams().toArray());
    }

    /**
     * 根据条件
     * @param searchParams
     * @return
     */
    private static WhereClause buildWhereClause(CarSearchParams searchParams) {
        List<Object> placeHolderParams = new ArrayList<>();
        StringBuilder sql = new StringBuilder();
        String keyWord = searchParams.getKeyWord();
        Integer brandId = searchParams.getBrandId();
        Integer typeId = searchParams.getTypeId();
        Integer priceId = searchParams.getPriceId();
        String startDate = searchParams.getStartDate();
        String endDate = searchParams.getEndDate();
        if (StringUtils.isNotBlank(keyWord)) {
            sql.append(" and name like concat('%',?,'%') ");
            placeHolderParams.add(keyWord);
        }
        if (typeId.equals(ALL_TYPE_ID)) {
            if (brandId != null && !brandId.equals(ALL_BRAND_ID)) {
                sql.append(" and typeid in (select id from t_type where brandid=?) ");
                placeHolderParams.add(brandId);
            }
        }

        if (!typeId.equals(ALL_TYPE_ID)) {
            sql.append(" and typeid=? ");
            placeHolderParams.add(typeId);
        }
        if (!priceId.equals(ALL_PRICE_RANGE_ID)) {
            sql.append(" and price>=(select min from t_price where id=?) and price<=(select max from t_price where id=?) ");
            placeHolderParams.add(priceId);
            placeHolderParams.add(priceId);
        }
        if (StringUtils.isNotBlank(startDate)) {
            sql.append(" and publishdate>=? ");
            placeHolderParams.add(startDate);
        }
        if (StringUtils.isNotBlank(endDate)) {
            sql.append(" and publishdate<=? ");
            placeHolderParams.add(endDate);
        }
        WhereClause whereClause = new WhereClause();
        whereClause.setSql(sql);
        whereClause.setParams(placeHolderParams);
        return whereClause;
    }

    /**
     * 这个对象包含了动态拼接后得到的条件对应的SQL语句
     * 以及当前语句中对应占位符参数的值
     */
    @Data
    static class WhereClause {
        /**
         * 拼接得到的SQL语句
         */
        private StringBuilder sql;
        /**
         * 拼接出来的SQL语句对应需要填充的占位符参数的值
         */
        private List<Object> params;
    }
}
